// Main.cpp
// (c) 2011, Charles Lechasseur
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "stdafx.h"
#include "Main.h"

#include "Platform.h"
#include "Exceptions.h"
#include <StCoInitialize.h>


//
// Program entry point. Will fork to 32-bit or 64-bit implementation
// depending on the target platform.
//
// @param p_hInstance Handle to application instance.
// @param p_hPrevInstance Ignored; always NULL.
// @param p_pCmdLine Pointer to command-line.
// @param p_CmdShow Flags indicating how the application window should be shown; ignored.
// @return Application return value.
//
int APIENTRY WinMain(HINSTANCE p_hInstance,
                     HINSTANCE /*p_hPrevInstance*/,
                     LPSTR     p_pCmdLine,
                     int       /*p_CmdShow*/)
{
    int retValue = 0;

    // Parse command-line and make sure it is complete.
    RG64::CommandLine cmdLine(p_pCmdLine);
    try {
        if (cmdLine.Complete() && ::PathFileExistsA(cmdLine.DllName().c_str())) {
            // Check bitness of the DLL passed in.
            bool is64bit = RG64::Is64Binary(cmdLine.DllName());

            // Initialize COM so that DLLs can use it in their init routine.
            StCoInitialize initCom;

            // Call appropriate function.
            if (is64bit) {
                retValue = RG64::Regsvr64_64bit(cmdLine);
            } else {
                retValue = RG64::Regsvr64_32bit(cmdLine);
            }
        } else if (!cmdLine.IsSilent()) {
            // Show help.
            ATL::CString helpStr(MAKEINTRESOURCE(IDS_HELP));
            ATL::CString helpTitle(MAKEINTRESOURCE(IDS_APP_TITLE));
            ::MessageBox(0, (LPCTSTR) helpStr, (LPCTSTR) helpTitle, MB_OK | MB_ICONEXCLAMATION);
            retValue = 1;
        }
    } catch (const RG64::Win32Exception& p_Win32Exception) {
        if (!cmdLine.IsSilent()) {
            ATL::CStringA title(MAKEINTRESOURCEA(IDS_APP_TITLE));
            ::MessageBoxA(0, p_Win32Exception.what(), (LPCSTR) title, MB_OK | MB_ICONERROR);
        }
        retValue = static_cast<int>(p_Win32Exception.ErrorCode());
    } catch (const std::exception& p_Exception) {
        if (!cmdLine.IsSilent()) {
            ATL::CStringA title(MAKEINTRESOURCEA(IDS_APP_TITLE));
            ::MessageBoxA(0, p_Exception.what(), (LPCSTR) title, MB_OK | MB_ICONERROR);
        }
        retValue = -1;
    }

    return retValue;
}
